<template>
  <div class="app-container">
    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="名称" prop="name">
        <el-input
          v-model="queryParams.name"
          placeholder="请输入名称"
          clearable
          size="small"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="流程分类" prop="category">
        <el-select v-model="queryParams.category" placeholder="请选择流程分类">
          <el-option
            v-for="dict in flowProcessCategory"
            :key="dict.dictValue"
            :label="dict.dictLabel"
            :value="dict.dictValue"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="业务类型" prop="type">
        <el-select v-model="queryParams.type" placeholder="请选择业务类型">
          <el-option label="动态表单" value="form"/>
          <el-option label="系统业务" value="business"/>
        </el-select>
      </el-form-item>
      <el-form-item label="部署时间" prop="deploymentTime">
        <el-date-picker clearable size="small"
                        v-model="queryParams.deploymentTime"
                        type="date"
                        value-format="yyyy-MM-dd"
                        placeholder="选择时间">
        </el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          plain
          icon="el-icon-upload"
          size="mini"
          @click="handleImport"
        >导入
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          plain
          icon="el-icon-plus"
          size="mini"
          @click="handleLoadXml"
        >新建流程
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
    </el-row>

    <el-table v-loading="loading" fit :data="definitionList">
      <el-table-column label="流程编号" align="left" prop="id" width="450" :show-overflow-tooltip="true"/>
      <el-table-column label="流程标识" align="left" prop="flowKey" width="150" :show-overflow-tooltip="true"/>
      <el-table-column label="流程分类" align="center" prop="category" :formatter="flowProcessCategoryFormat"/>
      <el-table-column label="流程名称" align="center" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <el-button type="text" @click="handleReadImage(scope.row.deploymentId)">
            <span>{{ scope.row.name }} </span>
          </el-button>
        </template>
      </el-table-column>
      <el-table-column label="流程版本" align="center">
        <template slot-scope="scope">
          <el-tag size="medium">v{{ scope.row.version }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="业务类型" align="center">
        <template slot-scope="scope">
          <el-tag type="success" v-if="scope.row.type=='form'">动态表单</el-tag>
          <el-tag type="info" v-else-if="scope.row.type=='business'">系统业务</el-tag>
          <label v-else>未设置</label>
        </template>
      </el-table-column>
      <el-table-column label="业务表单" align="center" :show-overflow-tooltip="true">
        <template slot-scope="scope">
          <el-button v-if="scope.row.type=='form'" type="text" @click="handleForm(scope.row.formId,scope.row.formName)">
            <span>{{ scope.row.formName }}</span>
          </el-button>
          <el-button v-else-if="scope.row.type=='business'" type="text"
                     @click="handleBusinessForm(scope.row.businessName,scope.row.businessURL)">
            <span>{{ scope.row.businessName }}</span>
          </el-button>
          <label v-else>未设置</label>
        </template>
      </el-table-column>
      <el-table-column label="状态" align="center">
        <template slot-scope="scope">
          <el-tag type="success" v-if="scope.row.suspensionState === 1">激活</el-tag>
          <el-tag type="warning" v-if="scope.row.suspensionState === 2">挂起</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="部署时间" align="center" prop="deploymentTime" width="180">
        <template slot-scope="scope">
          <span>{{ scope.row.deploymentTime.slice(0,16)}}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <el-dropdown>
            <span class="el-dropdown-link">
              更多操作<i class="el-icon-arrow-down el-icon--right"></i>
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item icon="el-icon-edit" @click.native="handleLoadXml(scope.row)">
                设计
              </el-dropdown-item>
              <el-dropdown-item icon="el-icon-edit-outline" @click.native="handleUpdate(scope.row)">
                编辑
              </el-dropdown-item>
              <el-dropdown-item icon="el-icon-connection" @click.native="handleAddForm(scope.row)">
                业务关联
              </el-dropdown-item>
              <el-dropdown-item icon="el-icon-video-pause" @click.native="handleUpdateSuspensionState(scope.row)"
                                v-if="scope.row.suspensionState === 1">
                挂起
              </el-dropdown-item>
              <el-dropdown-item icon="el-icon-video-play" @click.native="handleUpdateSuspensionState(scope.row)"
                                v-if="scope.row.suspensionState === 2">
                激活
              </el-dropdown-item>
              <el-dropdown-item icon="el-icon-delete" @click.native="handleDelete(scope.row)">
                删除
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 修改流程分类对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" label-width="80px" :model="form" :rules="rules">
        <el-form-item label="流程名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入流程名称"/>
        </el-form-item>
        <el-form-item label="流程分类" prop="category">
          <el-select v-model="form.category" placeholder="请选择流程分类" :style="{width: '100%'}">
            <el-option
              v-for="dict in flowProcessCategory"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            />
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>
    <!-- bpmn20.xml导入对话框 -->
    <el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
      <el-upload
        ref="upload"
        :limit="1"
        accept=".xml"
        :headers="upload.headers"
        :action="upload.url + '?name=' + upload.name+'&category='+ upload.category"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          <el-form ref="fileForm" label-width="80px" size="medium" :model="upload" :rules="rules">
            <el-form-item label="流程名称" prop="name">
              <el-input v-model="upload.name" placeholder="请输入流程名称"/>
            </el-form-item>
            <el-form-item label="流程分类" prop="category">
              <el-select v-model="upload.category" placeholder="请选择流程分类" :style="{width: '100%'}">
                <el-option
                  v-for="dict in flowProcessCategory"
                  :key="dict.dictValue"
                  :label="dict.dictLabel"
                  :value="dict.dictValue"
                />
              </el-select>
            </el-form-item>
          </el-form>
        </div>
        <div class="el-upload__tip" style="color:red" slot="tip">提示：仅允许导入“bpmn20.xml”格式文件！</div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitFileForm">确 定</el-button>
        <el-button @click="upload.open = false">取 消</el-button>
      </div>
    </el-dialog>
    <!-- 流程图 -->
    <el-dialog :title="readImage.title" :visible.sync="readImage.open" width="60%" append-to-body>
      <flow :xmlData="xmlData"/>
    </el-dialog>
    <!--表单配置详情-->
    <el-dialog :title="formTitle" :visible.sync="formConfOpen" width="60%" append-to-body>
      <parser :key="new Date().getTime()" :form-conf="formConf"/>
    </el-dialog>
    <!--业务表单配置详情,存在问题，无法路由-->
    <el-dialog :title="businessFormTitle" :visible.sync="businessFormOpen" width="60%" append-to-body>
      <iframe :src="businessFormURL" style="width:100%; height: 600px; border: 0"></iframe>
    </el-dialog>
    <!--关联业务对话框-->
    <el-dialog :title="formDeployTitle" :visible.sync="formDeployOpen" width="60%" append-to-body>
      <el-tabs type="border-card">
        <el-tab-pane label="挂载表单">
          <el-row :gutter="24">
            <el-col :span="10" :xs="24">
              <el-table
                ref="singleTable"
                :data="formList"
                border
                highlight-current-row
                @current-change="handleCurrentChange"
                style="width: 100%">
                <el-table-column label="表单编号" align="center" prop="id"/>
                <el-table-column label="表单名称" align="center" prop="name"/>
                <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
                  <template slot-scope="scope">
                    <el-button type="text" size="mini" icon="el-icon-connection" @click="submitFormDeploy(scope.row)">
                      关联表单
                    </el-button>
                  </template>
                </el-table-column>
              </el-table>

              <pagination
                small
                layout="prev, pager, next"
                v-show="formTotal>0"
                :total="formTotal"
                :page.sync="formQueryParams.pageNum"
                :limit.sync="formQueryParams.pageSize"
                @pagination="ListFormDeploy"
              />
            </el-col>
            <el-col :span="14" :xs="24">
              <div v-if="currentRow">
                <parser :key="new Date().getTime()" :form-conf="currentRow"/>
              </div>
            </el-col>
          </el-row>
        </el-tab-pane>
        <el-tab-pane label="系统业务">
          <el-form ref="businessForm" :model="formDeployParam" :rules="businessRules" size="medium" label-width="120px">
            <el-form-item label="关联业务名称" prop="businessName">
              <el-input v-model="formDeployParam.businessName" placeholder="请输入关联业务名称" clearable
                        :style="{width: '100%'}">
              </el-input>
            </el-form-item>
            <el-form-item label="回调接口API" prop="businessAPI">
              <el-input v-model="formDeployParam.businessAPI" placeholder="请输入回调接口API" clearable
                        :style="{width: '100%'}">
              </el-input>
            </el-form-item>
            <el-form-item label="详情表单示例" prop="businessURL">
              <el-input v-model="formDeployParam.businessURL" placeholder="请输入流程详情URL" clearable
                        :style="{width: '100%'}">
              </el-input>
            </el-form-item>
            <el-form-item size="large">
              <el-button type="primary" @click="submitBusinessDeploy">提交</el-button>
            </el-form-item>
          </el-form>
        </el-tab-pane>
      </el-tabs>
      <el-tag type="danger" class="mt10">提示：动态表单和系统业务选其一生效</el-tag>
    </el-dialog>
    <router-view/>
  </div>
</template>

<script>
  import {
    listDefinition,
    updateState,
    getDeployment,
    delDeployment,
    updateDeployment,
    readXml
  } from '@/api/flowable/definition'
  import { getToken } from '@/utils/auth'
  import { listFlowform, getFlowform, getDeployForm, addDeployForm } from '@/api/flowable/form'
  import Parser from '@/components/parser/Parser'
  import flow from '@/views/flowable/task/record/flow'

  export default {
    name: 'Definition',
    components: {
      Parser,
      flow
    },
    data() {
      return {
        // 遮罩层
        loading: true,
        // 选中数组
        ids: [],
        // 非单个禁用
        single: true,
        // 非多个禁用
        multiple: true,
        // 显示搜索条件
        showSearch: true,
        // 总条数
        total: 0,
        // 流程定义表格数据
        definitionList: [],
        flowProcessCategory: [],
        // 弹出层标题
        title: '',
        // 是否显示弹出层
        open: false,
        formConfOpen: false,
        formTitle: '',
        businessFormOpen: false,
        businessFormTitle: '',
        businessFormURL: '',
        formDeployOpen: false,
        formDeployTitle: '',
        formList: [],
        formTotal: 0,
        formConf: {}, // 默认表单数据
        readImage: {
          open: false,
          src: ''
        },
        // bpmn.xml 导入
        upload: {
          // 是否显示弹出层（xml导入）
          open: false,
          // 弹出层标题（xml导入）
          title: '',
          // 是否禁用上传
          isUploading: false,
          name: null,
          category: null,
          // 设置上传的请求头部
          headers: { Authorization: 'Bearer ' + getToken() },
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + '/flowable/definition/import'
        },
        // 查询参数
        queryParams: {
          pageNum: 1,
          pageSize: 10,
          name: null,
          category: null,
          key: null,
          tenantId: null,
          deploymentTime: null,
          derivedFrom: null,
          derivedFromRoot: null,
          parentDeploymentId: null,
          engineVersion: null
        },
        formQueryParams: {
          pageNum: 1,
          pageSize: 10
        },
        // 挂载业务到流程实例
        formDeployParam: {
          id: null,
          type: null,
          formId: null,
          deployId: null,
          businessName: null,
          businessURL: null,
          businessAPI: null
        },
        currentRow: null,
        // xml
        xmlData: '',
        // 表单参数
        form: {},
        // 表单校验
        rules: {
          name: [
            { required: true, message: '流程名称不能为空', trigger: 'blur' }
          ],
          category: [
            { required: true, message: '流程分类不能为空', trigger: 'blur' }
          ]
        },
        businessRules: {
          businessName: [{
            required: true,
            message: '请输入关联业务名称',
            trigger: 'blur'
          }]
        }
      }
    },
    created() {
      this.getDicts('flow_process_category').then(response => {
        this.flowProcessCategory = response.data
      })
      this.getList()
    },
    methods: {
      /** 查询流程定义列表 */
      getList() {
        this.loading = true
        listDefinition(this.queryParams).then(response => {
          this.definitionList = response.data.records
          this.total = response.data.total
          this.loading = false
        })
      },
      // 流程分类
      flowProcessCategoryFormat(row, column) {
        return this.selectDictLabel(this.flowProcessCategory, row.category)
      },
      // 取消按钮
      cancel() {
        this.open = false
        this.reset()
      },
      // 表单重置
      reset() {
        this.form = {
          id: null,
          name: null,
          category: null
        }
        this.resetForm('form')
      },
      /** 搜索按钮操作 */
      handleQuery() {
        this.queryParams.pageNum = 1
        this.getList()
      },
      /** 重置按钮操作 */
      resetQuery() {
        this.resetForm('queryForm')
        this.handleQuery()
      },
      /** 跳转到流程设计页面 */
      handleLoadXml(row) {
        this.$router.push({ path: '/flowable/definition/model', query: { deployId: row.deploymentId } })
      },
      /** 流程图查看 */
      handleReadImage(deploymentId) {
        this.readImage.title = '流程图'
        this.readImage.open = true
        readXml(deploymentId).then(res => {
          this.xmlData = res.data
        })
      },
      /** 表单查看 */
      handleForm(formId, formName) {
        getFlowform(formId).then(res => {
          this.formTitle = '动态表单详情' + '【' + formName + '】'
          this.formConfOpen = true
          this.formConf = res.data.content
        })
      },
      /** 业务查看 */
      handleBusinessForm(businessName, businessURL) {
        this.businessFormTitle = '业务表单详情' + '【' + businessName + '】'
        this.businessFormOpen = true
        this.businessFormURL = businessURL
      },
      /** 挂载表单弹框 */
      handleAddForm(row) {
        this.ListFormDeploy()
        this.InfoFormDeploy(row.deploymentId)
        this.formDeployOpen = true
        this.formDeployTitle = '业务关联'
      },
      /** 挂载业务详情 */
      InfoFormDeploy(id) {
        getDeployForm(id).then(response => {
          this.formDeployParam = response.data
          this.formDeployParam.deployId = id
        })
      },
      /** 挂载表单列表 */
      ListFormDeploy() {
        listFlowform(this.formQueryParams).then(res => {
          this.formList = res.rows
          this.formTotal = res.total
        })
      },
      /** 挂载表单 */
      submitFormDeploy(row) {
        this.formDeployParam.formId = row.id
        this.formDeployParam.type = 'form'
        addDeployForm(this.formDeployParam).then(res => {
          this.msgSuccess(res.msg)
          this.$modal
          this.formDeployOpen = false
          this.getList()
        })
      },
      /** 挂载业务 */
      submitBusinessDeploy() {
        this.$refs['businessForm'].validate(valid => {
          if (valid) {
            this.formDeployParam.type = 'business'
            addDeployForm(this.formDeployParam).then(res => {
              this.msgSuccess(res.msg)
              this.formDeployOpen = false
              this.getList()
            })
          }
        })
      },
      handleCurrentChange(data) {
        if (data) {
          this.currentRow = data.content
        }
      },
      /** 挂起/激活流程 */
      handleUpdateSuspensionState(row) {
        let state = 1
        if (row.suspensionState === 1) {
          state = 2
        }
        const params = {
          deployId: row.deploymentId,
          state: state
        }
        updateState(params).then(res => {
          this.msgSuccess(res.msg)
          this.getList()
        })
      },
      /** 修改分类 */
      handleUpdate(row) {
        this.reset()
        getDeployment(row.deploymentId).then(response => {
          this.form = response.data
          this.open = true
          this.title = '修改流程分类'
        })
      },
      /** 保存分类 */
      submitForm() {
        this.$refs['form'].validate(valid => {
          updateDeployment(this.form).then(response => {
            this.msgSuccess('修改成功')
            this.open = false
            this.getList()
            this.reset()
          })
        })
      },
      /** 删除按钮操作 */
      handleDelete(row) {
        const params = {
          deployId: row.deploymentId
        }
        this.$confirm('是否确认删除流程定义名称为"' + row.name + '"的数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(function() {
          return delDeployment(params)
        }).then(() => {
          this.getList()
          this.msgSuccess('删除成功')
        })
      },
      /** 导入bpmn.xml文件 */
      handleImport() {
        this.upload.title = 'bpmn20.xml文件导入'
        this.upload.open = true
      },
      // 文件上传中处理
      handleFileUploadProgress(event, file, fileList) {
        this.upload.isUploading = true
      },
      // 文件上传成功处理
      handleFileSuccess(response, file, fileList) {
        this.upload.open = false
        this.upload.isUploading = false
        this.$refs.upload.clearFiles()
        this.$message(response.msg)
        this.getList()
      },
      // 提交上传文件
      submitFileForm() {
        this.$refs['fileForm'].validate(valid => {
          if (valid) {
            this.$refs.upload.submit()
          }
        })
      }
    }
  }
</script>
